//! \file PathSearch.h
//! \brief Defines the <code>fullsail_ai::algorithms::PathSearch</code> class interface.
//! \author Cromwell D. Enage
#ifndef _FULLSAIL_AI_PATH_PLANNER_ALGORITHMS_PATH_SEARCH_H_
#define _FULLSAIL_AI_PATH_PLANNER_ALGORITHMS_PATH_SEARCH_H_

#include "../Core/Tile.h"
#include "../Core/TileMap.h"
#include <vector>
#include <map>
#include "..\Core\PriorityQueue.h"
using namespace std;

#define heurWeight 1.1f

namespace fullsail_ai { namespace algorithms {

	class PathSearch
	{
		struct PlannerNode
		{
			PlannerNode* parent;
			Tile* m_tile;
			float givenCost;
			float heuristicCost;
			float finalCost;
			PlannerNode(Tile* tile, float given,float heuristic):m_tile(tile),givenCost(given),heuristicCost(heuristic)
			{
				parent = NULL;
				finalCost = givenCost + (heuristicCost*heurWeight);
			}
		};


		// priority queue for open nodes
		PriorityQueue<PlannerNode*> openList;

		// function for finding the distance
		float TileDistance(Tile* tile1,Tile* tile2);
		float SuccessorDistance();
		// a map for checking the duplicates
		map<Tile*,PlannerNode*> createdMap;

		TileMap* tileMap;
		Tile* startTile,* goalTile;

		// helper function for finding the adjacent tiles
		vector<Tile*> adjacents;
		void FindAdjacents(Tile* tile);
		// helper function to build the solution to send back
		vector<Tile const*> solution;
		void BuildSolution(PlannerNode* node);
		// bool for the isDone check
		bool imDone;


	public:
		//! \brief Default constructor.
		PathSearch();

		//! \brief Destructor.
		~PathSearch();

		//! \brief Sets the tile map.
		//!
		//! Invoked when the user opens a tile map file.
		//!
		//! \param   _tileMap  the data structure that this algorithm will use
		//!                    to access each tile's location and weight data.
		void initialize(TileMap* _tileMap);

		//! \brief Enters and performs the first part of the algorithm.
		//!
		//! Invoked when the user presses one of the play buttons.
		//!
		//! \param   startRow         the row where the start tile is located.
		//! \param   startColumn      the column where the start tile is located.
		//! \param   goalRow          the row where the goal tile is located.
		//! \param   goalColumn       the column where the goal tile is located.
		void enter(int startRow, int startColumn, int goalRow, int goalColumn);

		//! \brief Returns <code>true</code> if and only if no nodes are left open.
		//!
		//! \return  <code>true</code> if no nodes are left open, <code>false</code> otherwise.
		bool isDone() const;

		//! \brief Performs the main part of the algorithm until the specified time has elapsed or
		//! no nodes are left open.
		void update(long timeslice);

		//! \brief Returns an unmodifiable view of the solution path found by this algorithm.
		std::vector<Tile const*> const getSolution() const;

		//! \brief Resets the algorithm.
		void exit();

		//! \brief Uninitializes the algorithm before the tile map is unloaded.
		void shutdown();
	};
}}  // namespace fullsail_ai::algorithms

#endif  // _FULLSAIL_AI_PATH_PLANNER_ALGORITHMS_PATH_SEARCH_H_

